// 源于Inferno utils/6l/l.h及相关文件。
// https:
// 
// 版权所有©1994-1999朗讯科技有限公司。保留所有权利。
// 版权所有©1995-1997 C H Forsyth(forsyth@terzarima.net)
// 部分版权©1997-1999维塔诺瓦有限公司
// 部分版权©2000-2007维塔诺瓦控股有限公司（www.vitanuova.com）
// 部分版权©20042006布鲁斯·埃利斯
// 修订版权©2000-2007朗讯科技有限公司及其他
// 部分版权©2009 Go作者。保留所有权利。
// 
// 特此免费授予获得本软件及相关文档文件（以下简称“软件”）副本
// 的任何人在本软件中不受限制地处理
// 的权利，包括但不限于
// 使用、复制、修改、合并、发布、分发、再许可的权利，和/或出售本软件的
// 副本，并允许提供本软件的人员在以下条件下这样做：
// 
// 上述版权声明和本许可声明应包含在
// 本软件的所有副本或大部分中。
// 
// 本软件按“原样”提供，不提供任何形式的明示或暗示担保，包括但不限于适销性担保、
// 适用于特定用途和非侵权性担保。在任何情况下，
// 作者或版权持有人均不对任何索赔、损害赔偿或其他
// 责任承担责任，无论是合同诉讼、侵权诉讼还是其他诉讼，均由
// 因本软件或本软件的使用或其他交易引起，或与本软件或本软件的使用或其他交易有关。

package sym

import "cmd/internal/objabi"

// 符号种类描述由符号表示的内存种类。
type SymKind uint8

// 定义的符号类值。
// 
// TODO（rsc）：给出惯用的Go名称。
// go:generate stringer-type=symckind 
const (
	Sxxx SymKind = iota
	STEXT
	SELFRXSECT
	SMACHOPLT

	// 只读部分。
	STYPE
	SSTRING
	SGOSTRING
	SGOFUNC
	SGCBITS
	SRODATA
	SFUNCTAB

	SELFROSECT

	// 带重新定位的只读节。
	// 
	// 将上述类型的STYPE-SFUNCTAB写入。默认情况下为rodata节。
	// 链接共享对象时，一些概念上的“只读”类型需要通过重新定位写入
	// 并将其放在名为
	// ”的部分中。rodata与系统链接器的交互很差。GNU链接器
	// 支持这种情况，在应用
	// “.data.rel.ro.XXX”的部分设置为只读保护，因此，当Go链接器创建一个共享的
	// 重新定位后，动态链接器会将名称为
	// 对象时，它会检查上述类型的所有对象，并将任何
	// 重新定位到其下面相应类型的对象，然后将其写入具有适当魔法名称的部分。
	STYPERELRO
	SSTRINGRELRO
	SGOSTRINGRELRO
	SGOFUNCRELRO
	SGCBITSRELRO
	SRODATARELRO
	SFUNCTABRELRO

	// 部分。数据雷尔。如果存在，则为ro，否则为。罗达。
	STYPELINK
	SITABLINK
	SSYMTAB
	SPCLNTAB

	// 可写部分。
	SFirstWritable
	SBUILDINFO
	SELFSECT
	SMACHO
	SMACHOGOT
	SWINDOWS
	SELFGOT
	SNOPTRDATA
	SINITARR
	SDATA
	SXCOFFTOC
	SBSS
	SNOPTRBSS
	SLIBFUZZER_EXTRA_COUNTER
	STLSBSS
	SXREF
	SMACHOSYMSTR
	SMACHOSYMTAB
	SMACHOINDIRECTPLT
	SMACHOINDIRECTGOT
	SFILEPATH
	SDYNIMPORT
	SHOSTOBJ
	SUNDEFEXT // 用于外部链接器解析的未定义符号

	// 调试信息部分
	SDWARFSECT
	// 矮化符号类型
	SDWARFCUINFO
	SDWARFCONST
	SDWARFFCN
	SDWARFABSFCN
	SDWARFTYPE
	SDWARFVAR
	SDWARFRANGE
	SDWARFLOC
	SDWARFLINES
)

// ABISYMKINDTOSYMMIND将从对象文件读取的值（cmd/internal/objabi.SYMMIND类型的
// 映射到SYMMIND类型的值）。
var AbiSymKindToSymKind = [...]SymKind{
	objabi.Sxxx:                     Sxxx,
	objabi.STEXT:                    STEXT,
	objabi.SRODATA:                  SRODATA,
	objabi.SNOPTRDATA:               SNOPTRDATA,
	objabi.SDATA:                    SDATA,
	objabi.SBSS:                     SBSS,
	objabi.SNOPTRBSS:                SNOPTRBSS,
	objabi.STLSBSS:                  STLSBSS,
	objabi.SDWARFCUINFO:             SDWARFCUINFO,
	objabi.SDWARFCONST:              SDWARFCONST,
	objabi.SDWARFFCN:                SDWARFFCN,
	objabi.SDWARFABSFCN:             SDWARFABSFCN,
	objabi.SDWARFTYPE:               SDWARFTYPE,
	objabi.SDWARFVAR:                SDWARFVAR,
	objabi.SDWARFRANGE:              SDWARFRANGE,
	objabi.SDWARFLOC:                SDWARFLOC,
	objabi.SDWARFLINES:              SDWARFLINES,
	objabi.SLIBFUZZER_EXTRA_COUNTER: SLIBFUZZER_EXTRA_COUNTER,
}

// 只读是构成只读部分的符号类型。在某些
// 情况下，如果需要重新安置，则使用RELOMAP将其转换为
// rel ro区段。
var ReadOnly = []SymKind{
	STYPE,
	SSTRING,
	SGOSTRING,
	SGOFUNC,
	SGCBITS,
	SRODATA,
	SFUNCTAB,
}

// RelROMap描述了将只读符号转换为rel-ro 
// 符号的过程。
var RelROMap = map[SymKind]SymKind{
	STYPE:     STYPERELRO,
	SSTRING:   SSTRINGRELRO,
	SGOSTRING: SGOSTRINGRELRO,
	SGOFUNC:   SGOFUNCRELRO,
	SGCBITS:   SGCBITSRELRO,
	SRODATA:   SRODATARELRO,
	SFUNCTAB:  SFUNCTABRELRO,
}

// 如果类型是数据类型，IsData返回true。
func (t SymKind) IsData() bool {
	return t == SDATA || t == SNOPTRDATA || t == SBSS || t == SNOPTRBSS
}
